package com.logic.config.web.messageService;

import cn.hutool.core.lang.ClassScanner;
import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.json.JSONUtil;
import com.logic.config.web.annotation.ActionController;
import com.logic.config.web.annotation.ActionMethod;
import com.logic.config.netty.web.model.message.ActionBody;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;

public class WSService {
    public static Object actionService(ActionBody actionBody) {
        Integer mainRoute1 = actionBody.getMainRoute();
        Integer subRoute1 = actionBody.getSubRoute();
        String token = actionBody.getToken();
        cn.hutool.json.JSONObject data = actionBody.getData();
        String actionPackage = "com.game.modular.act";
        Set<Class<?>> classes = ClassScanner.scanPackageByAnnotation(actionPackage, ActionController.class);
        AtomicReference<Object> result = new AtomicReference<>();
        classes.forEach(clazz -> {
            String simpleName = clazz.getSimpleName();
            simpleName = simpleName.substring(0, 1).toLowerCase() + simpleName.substring(1);

            ActionController actionController = clazz.getAnnotation(ActionController.class);
            int mainRoute = actionController.value();

            Method[] methods = clazz.getDeclaredMethods();



            for (Method method : methods) {
                if (method.isAnnotationPresent(ActionMethod.class)) {
                    ActionMethod annotation = method.getAnnotation(ActionMethod.class);
                    int subRoute = annotation.value();
                    if (mainRoute == mainRoute1 && subRoute == subRoute1) {
                        Object bean = SpringUtil.getBean(simpleName);
                        Method[] targets = bean.getClass().getDeclaredMethods();
                        Method method1 = null;
                        for (Method target : targets) {
                            if (target.getName().equals(method.getName())) {
                                method1 = target;
                                break;
                            }
                        }
                        assert method1 != null;
                        Class<?>[] parameterType = method.getParameterTypes();
                        // 方法参数列表
                        Object[] args = new Object[parameterType.length];
                        for (int i = 0; i < parameterType.length; i++) {
                            Class<?> aClass = parameterType[i];
                            args[0] = token;
                            Object bean1 = JSONUtil.toBean(data, aClass);
                            args[i] = bean1;
                        }
                        try {
                           result.set(method.invoke(bean, args));
                        } catch (IllegalAccessException | InvocationTargetException e) {
                            throw new RuntimeException(e);
                        }
                    }
                }
            }
        });
        return result.get();
    }

}
